package org.batatasframework.logger;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 
 * @author jackson
 *
 * @param <T>
 */
public class FieldAmendmentRecordHandler<T extends FieldAmendmentRecordable> implements Iterable<T>{
	private final FieldAmendmentRecordBuilder<T> builder;
	private final List<T> items = new ArrayList<>();
	
	public static interface FieldAmendmentRecordBuilder<T extends FieldAmendmentRecordable>{
		T build();
	}
	
	public FieldAmendmentRecordHandler(FieldAmendmentRecordBuilder<T> builder){
		this.builder = builder;
	}
	
	@Override
	public Iterator<T> iterator() {
		return items.iterator();
	}
	
	private T buildRecord(String fieldName, String oldValue, String newValue){
		T field = builder.build();
		field.setFieldName(fieldName);
		field.setOldValue(oldValue);
		field.setNewValue(newValue);
		return field;
	}
	
	public void add(String fieldName, String oldValue, String newValue){
		items.add(buildRecord(fieldName, oldValue, newValue));
	}

	public void add(String fieldName, Object oldValue, Object newValue){
		items.add(buildRecord(fieldName, oldValue.toString(), newValue.toString()));
	}
	
	public int parseValue(String fieldName, int oldValue, int newValue){
		if(oldValue != newValue){
			add(fieldName, Integer.toString(oldValue), Integer.toString(newValue));
		}
		return newValue;
	}
	
	public long parseValue(String fieldName, long oldValue, long newValue){
		if(oldValue != newValue){
			add(fieldName, Long.toString(oldValue), Long.toString(newValue));
		}
		return newValue;
	}
	
	public float parseValue(String fieldName, float oldValue, float newValue){
		if(oldValue != newValue){
			add(fieldName, Float.toString(oldValue), Float.toString(newValue));
		}
		return newValue;
	}
	
	public double parseValue(String fieldName, double oldValue, double newValue){
		if(oldValue != newValue){
			add(fieldName, Double.toString(oldValue), Double.toString(newValue));
		}
		return newValue;
	}
	
	public boolean parseValue(String fieldName, boolean oldValue, boolean newValue){
		if(oldValue != newValue){
			add(fieldName, String.valueOf(oldValue), String.valueOf(newValue));
		}
		return newValue;
	}
	
	public char parseValue(String fieldName, char oldValue, char newValue){
		if(oldValue != newValue){
			add(fieldName, String.valueOf(oldValue), String.valueOf(newValue));
		}
		return newValue;
	}
	
	public short parseValue(String fieldName, short oldValue, short newValue){
		if(oldValue != newValue){
			add(fieldName, Integer.toString(oldValue), Integer.toString(newValue));
		}
		return newValue;
	}
	
	public byte parseValue(String fieldName, byte oldValue, byte newValue){
		if(oldValue != newValue){
			add(fieldName, Integer.toString(oldValue), Integer.toString(newValue));
		}
		return newValue;
	}
	
	private final static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
	private final static String NULL_VALUE = "[空值]";
	
	public Date parseValue(String fieldName, Date oldValue, Date newValue){
		return parseValue(fieldName, oldValue, newValue, DATE_FORMAT, NULL_VALUE);
	}

	public <V> V parseValue(String fieldName, V oldValue, V newValue){
		if(oldValue == null){
			if(newValue != null){
				//由空值改为非空值的情况
				add(fieldName, NULL_VALUE, newValue.toString());
			}
		}else if(!oldValue.equals(newValue)){
			if(newValue == null){
				add(fieldName, oldValue.toString(), NULL_VALUE);
			}else{
				add(fieldName, oldValue.toString(), newValue.toString());
			}
		}
		return newValue;
	}
	
	public Date parseValue(String fieldName, Date oldValue, Date newValue, DateFormat format, String nullValue){
		if(oldValue == null){
			if(newValue != null){
				//由空值改为非空值的情况
				add(fieldName, nullValue, format.format(newValue));
			}
		}else if(!oldValue.equals(newValue)){
			if(newValue == null){
				add(fieldName, format.format(oldValue), nullValue);
			}else{
				add(fieldName, format.format(oldValue), format.format(newValue));
			}
		}
		return newValue;
	}
}
